// 发布-订阅模式
class EvevtEmitter {
  constructor() {
    this.handler = {};
  }

  // 安装事件监听，接受事件名和回调函数作为参数
  on(type, cb) {
    if (this.handler[type]) {
      this.handler[type].push(cb);
    } else {
      this.handler[type] = [cb];
    }
  }

  // emit用于触发目标事件，接受事件名和监听函数的参数作为参数
  emit(type, ...arg) {
    for (let cb of this.handler[type]) {
      cb(...arg);
    }
  }

  once(type, cb) {
    // 使用了AOP
    const wrapper = (...args) => {
      cb(...args);
      this.off(type, wrapper);
    };

    this.on(type, wrapper);
  }

  //移除某个事件回调队列中的回调函数
  off(type, cb) {
    const callbacks = this.handler[type];
    const index = callbacks.indexOf(cb);
    if (index !== -1) {
      callbacks.splice(index, 1);
    }
  }
}

let evevtEmitter = new EvevtEmitter();

evevtEmitter.once("listen", (data) => {
  console.log(data);
});

evevtEmitter.emit("listen", "emit event");
evevtEmitter.emit("listen", "emit event");

// 结果, 只打印了一次 emit event
